package mgo

// ===== Bulk Middleware =====

// BulkContext bulk 上下文信息
type BulkContext struct {
	C         *Collection
	B         *Bulk
	Result    *BulkResult // 执行结果
	BulkError *BulkError  // 执行错误信息
	OK        bool        // 是否成功
}

// BulkMiddleware bulk 操作中间件
type BulkMiddleware func(bulkContext *BulkContext, next func())

var bulkMiddlewares []BulkMiddleware

// RegisterBulkMiddleware bulk 中间件
func RegisterBulkMiddleware(middleware BulkMiddleware) {
	bulkMiddlewares = append(bulkMiddlewares, middleware)
}

func executeBulkMiddlewares(bulkContext *BulkContext, index int, originalFunc func()) {
	if index >= len(bulkMiddlewares) {
		originalFunc()
		return
	}

	// 创建下一个中间件的执行函数
	next := func() {
		executeBulkMiddlewares(bulkContext, index+1, originalFunc)
	}
	// 执行当前中间件
	bulkMiddlewares[index](bulkContext, next)
}

// ===== Insert Middleware =====

// InsertContext 插入上下文
type InsertContext struct {
	C     *Collection
	Docs  []interface{}
	Error error
}

// InsertMiddleware 插入中间件
type InsertMiddleware func(insertContext *InsertContext, next func())

// 存储注册的中间件
var insertMiddlewares []InsertMiddleware

// RegisterInsertMiddleware 注册插入中间件
func RegisterInsertMiddleware(insert InsertMiddleware) {
	insertMiddlewares = append(insertMiddlewares, insert)
}

func executeInsertMiddlewares(insertContext *InsertContext, index int, originalFunc func()) {
	if index >= len(insertMiddlewares) {
		originalFunc()
		return
	}

	// 创建下一个中间件的执行函数
	next := func() {
		executeInsertMiddlewares(insertContext, index+1, originalFunc)
	}
	// 执行当前中间件
	insertMiddlewares[index](insertContext, next)
}

// ===== Update Middleware =====

// UpdateContext 更新上下文信息
type UpdateContext struct {
	C          *Collection
	UpdateAll  bool
	Selector   interface{}
	Update     interface{}
	ChangeInfo *ChangeInfo // UpdateAll=true 且执行结果 next 之后才有效
	Error      error
}

// UpdateMiddleware 更新中间件
type UpdateMiddleware func(updateContext *UpdateContext, next func())

// 存储注册的中间件
var updateMiddlewares []UpdateMiddleware

// RegisterUpdateMiddleware 注册更新中间件
func RegisterUpdateMiddleware(middleware UpdateMiddleware) {
	updateMiddlewares = append(updateMiddlewares, middleware)
}

func executeUpdateMiddlewares(updateContext *UpdateContext, index int, originalFunc func()) {
	if index >= len(updateMiddlewares) {
		originalFunc()
		return
	}

	// 创建下一个中间件的执行函数
	next := func() {
		executeUpdateMiddlewares(updateContext, index+1, originalFunc)
	}
	// 执行当前中间件
	updateMiddlewares[index](updateContext, next)
}

// ===== Remove Middleware =====

// RemoveContext 删除上下文信息
type RemoveContext struct {
	C          *Collection
	RemoveAll  bool
	Selector   interface{}
	ChangeInfo *ChangeInfo // RemoveAll=true 且执行结果 next 之后才有效
	Error      error
}

// RemoveMiddleware 删除中间件
type RemoveMiddleware func(removeContext *RemoveContext, next func())

// 存储注册的中间件
var removeMiddlewares []RemoveMiddleware

// RegisterRemoveMiddleware 注册删除中间件
func RegisterRemoveMiddleware(middleware RemoveMiddleware) {
	removeMiddlewares = append(removeMiddlewares, middleware)
}

func executeRemoveMiddlewares(removeContext *RemoveContext, index int, originalFunc func()) {
	if index >= len(removeMiddlewares) {
		originalFunc()
		return
	}

	// 创建下一个中间件的执行函数
	next := func() {
		executeRemoveMiddlewares(removeContext, index+1, originalFunc)
	}
	// 执行当前中间件
	removeMiddlewares[index](removeContext, next)
}

// ===== Upsert Middleware =====

// UpsertContext 更新&添加上下文信息
type UpsertContext struct {
	C          *Collection
	Selector   interface{}
	Update     interface{}
	ChangeInfo *ChangeInfo
	Error      error
}

// UpsertMiddleware 更新中间件
type UpsertMiddleware func(upsertContext *UpsertContext, next func())

// 存储注册的中间件
var upsertMiddlewares []UpsertMiddleware

// RegisterUpsertMiddleware 注册更新中间件
func RegisterUpsertMiddleware(middleware UpsertMiddleware) {
	upsertMiddlewares = append(upsertMiddlewares, middleware)
}

func executeUpsertMiddlewares(upsertContext *UpsertContext, index int, originalFunc func()) {
	if index >= len(upsertMiddlewares) {
		originalFunc()
		return
	}

	// 创建下一个中间件的执行函数
	next := func() {
		executeUpsertMiddlewares(upsertContext, index+1, originalFunc)
	}
	// 执行当前中间件
	upsertMiddlewares[index](upsertContext, next)
}
